package org.infodavid.common.util;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.commons.lang.LocaleUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * The Class LocaleUtil.
 */
public final class LocaleUtil {

	/** The Constant log. */
	private static final Log LOGGER = LogFactory.getLog(LocaleUtil.class);

	/** The singleton. */
	private static WeakReference<LocaleUtil> singleton = null;

	/**
	 * returns the singleton.
	 * @return the utility
	 */
	public static synchronized LocaleUtil getInstance() {
		if (singleton == null || singleton.get() == null) {
			singleton = new WeakReference<LocaleUtil>(new LocaleUtil());
		}

		return singleton.get();
	}

	/** The is debug enabled. */
	private final boolean isDebugEnabled = LOGGER.isDebugEnabled();

	/**
	 * Instantiates a new locale utility.
	 */
	private LocaleUtil() {
		super();
	}

	/**
	 * Gets the locale.
	 * @param value the value
	 * @return the locale
	 */
	@SuppressWarnings({
	    "rawtypes", "unchecked"
	})
	public Locale getLocale(final String value) {
		Locale result;

		if (value == null) {
			result = null;
		}
		else {
			final List languages = LocaleUtils.countriesByLanguage(value.toLowerCase());
			final List countries = LocaleUtils.languagesByCountry(value.toUpperCase());
			final List locales = new ArrayList(languages);

			locales.retainAll(countries);

			if (locales.isEmpty()) {
				if (languages.isEmpty()) {
					result = countries.isEmpty() ? null : (Locale)countries.get(0);
				}
				else {
					result = (Locale)languages.get(0);
				}
			}
			else {
				result = (Locale)locales.get(0);
			}
		}

		if (isDebugEnabled) {
			LOGGER.debug("Locale converted from: " + value + " to: " + result);
		}

		return result;
	}
}
